/*******************************************************************************
 * This file is part of Crunch Graphics.
 *
 * Crunch Graphics is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * Crunch Graphics is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with
 * Crunch Graphics.  If not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************/

package com.crunch.graphics.gpu;

/** Base class for reference counted GPU objects.
 *
 *  Implementations should define the method void onRelease()
 *  to be called when the reference count drops to zero.
 *  This object should never be used directly; only subclass
 *  pointers should be used.
 */
public abstract class ReferenceCountedGpuObject extends GpuObject {
	/** Stores a reference to the GpuState.
	 */
	public ReferenceCountedGpuObject(GpuState state) {
		super(state);
		referenceCount = 0;
	}

	/** Returns the number of references to this object.
	 */
	public int getReferenceCount() {
		return referenceCount;
	}

	/** Increments the reference count.
	 */
	public void acquire() {
		++referenceCount;
	}

	/** Decrements the reference count.
	 */
	public void release() {
		--referenceCount;
		if (referenceCount == 0) {
			onRelease();
		} else if (referenceCount < 0) {
			throw new IllegalStateException("Invalid reference count: object has been released too many times");
		}
	}

	/** This method should be overridden to release GPU resources.
	 */
	protected abstract void onRelease();

	// the reference count for this object
	private int referenceCount;
}